package cn.zwx.learn.mybatis.example.croe.executor;

import cn.zwx.learn.mybatis.example.croe.cache.CacheKey;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 带缓存的执行器
 * @author zhangwenxue
 */
public class CachingExecutor implements Executor {

    private final static Logger logger = LoggerFactory.getLogger(CachingExecutor.class);
    /**
     * 二级缓存保存
     */
    private static final Map<Integer, Object> cache = new HashMap<>();
    SimpleExecutor simpleExecutor;
    public CachingExecutor(SimpleExecutor simpleExecutor) {
        this.simpleExecutor = simpleExecutor;
    }

    @Override
    public <T> T query(String statement, Object[] parameter, Class pojo) {
        // 构建缓存的key 这里采用简单hash
        CacheKey cacheKey = new CacheKey();
        cacheKey.update(statement);
        cacheKey.update(this.joinStr(parameter));
        if (cache.containsKey(cacheKey.getCode())){
            logger.info("命中缓存cacheKey：{}",cacheKey);
            return (T) cache.get(cacheKey.getCode());
        }
        // 查询SQL
        Object query = simpleExecutor.query(statement, parameter, pojo);
        // 放入缓存
        cache.put(cacheKey.getCode(),query);
        return (T) query;
    }

    /**
     * 为了命中缓存，把Object[]转换成逗号拼接的字符串，因为对象的HashCode都不一样
     */
    public String joinStr(Object[] objs){
        if (Objects.isNull(objs)){
            return "";
        }
      return StringUtils.join(objs,",");
    }

}
